package com.it.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.SystemClock;
import com.it.common.FrameResp;
import com.it.model.Chapter;
import com.it.service.IChapterService;
import com.it.utils.*;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @desc:
 * @author: panxiyi
 * @date: 2023/5/27 5:36 下午
 */

@RestController
@RequestMapping("/tool")
public class ToolController {


    @Autowired
    private IChapterService chapterService;


    @RequestMapping(value = "/gen_post_curl")
    public FrameResp genPostCurl(@RequestParam(value = "post_params", defaultValue = "") String postParams,
                                 @RequestParam(value = "req_url", defaultValue = "") String reqUrl) {

        System.out.println(postParams + " ==== " + reqUrl);

        try {
            postParams = URLDecoder.decode(postParams, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        postParams = postParams.replaceAll("\\[", "").replaceAll("]", "");

        if (!reqUrl.contains("http")) {
            reqUrl = "http://" + reqUrl;
        }
        String res = "curl -X POST -d '" + postParams + "'" + " '" + reqUrl + "'";
        return FrameResp.RET_SUCCESS(res);
    }

    @RequestMapping(value = "/del_zhuan_yi")
    public FrameResp delZhuanyi(@RequestParam(value = "post_params", defaultValue = "") String postParams) {

        System.out.println(postParams + " ==== ");

        try {
            postParams = URLDecoder.decode(postParams, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        postParams = postParams.replaceAll("\\\\", "");
        try {
            JSONObject jo = JSON.parseObject(postParams);
            //Logs.common.info(Pair.of("res1", jo.toJSONString()));
            return FrameResp.RET_SUCCESS(jo.toJSONString());
        } catch (Exception e) {
            try {
                JSONArray jsonArray = JSON.parseArray(postParams);
              //  Logs.common.info(Pair.of("res2", jsonArray.toJSONString()));
                return FrameResp.RET_SUCCESS(jsonArray.toJSONString());
            } catch (Exception e2) {
                //Logs.common.info(Pair.of("message", "parse error"));
            }
        }
        //Logs.common.info(Pair.of("res3", postParams));
        return FrameResp.RET_SUCCESS(postParams);
    }

    @Value("${file.upload.directory}")
    private String uploadDir;

    // 处理多个上传文件
//    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
//    public ResponseEntity<?> handleFileUpload(@RequestParam("file") MultipartFile[] files,


    @PostMapping("/upload")
    @Transactional
    public ResponseEntity<?> handleFileUpload(@RequestParam("file") MultipartFile file,
                                              @RequestParam(value = "book_id", defaultValue = "") Integer bookId) {
        String fileName = file.getOriginalFilename();
        System.out.println("file: " +file + " bookId: " + bookId);
        //String uploadDirectory = "uploads"; // 您可以更改为所需的上传目录
        try {
            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid file name");
            }
            // 获取文件后缀名
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
            // 保存文件到不同的目录
            Path destination;
            switch (fileExtension.toLowerCase()) {
                case "jpg":
                case "jpeg":
                case "png":
                case "gif":
                    destination = Paths.get(uploadDir, "images", getImgFileName(originalFilename));
                    break;
                case "zip":
                    destination = Paths.get(uploadDir, "archives", originalFilename);
                    break;
                default:
                    destination = Paths.get(uploadDir, "others", originalFilename);
            }

            // 创建目标文件夹，存在不做任何操作
            Files.createDirectories(destination.getParent());
            // 将上传的文件保存到目标路径
            Files.copy(file.getInputStream(), destination, StandardCopyOption.REPLACE_EXISTING);
            String resourceUrl = "/static/" + destination.toString().replace(uploadDir, "");
            // 如果是压缩文件，则解压
//            if ("zip".equalsIgnoreCase(fileExtension)) {
//                //unzip(destination, destination.getParent());
//                Path filePath = destination;
//                List<Chapter> chapters = decompressAndExtractBooks(filePath);
//                Logs.common.info(Pair.of("chapters", JSON.toJSONString(chapters)));
//                try {
//                    boolean res = chapterService.saveBatch(chapters);
//                    Logs.common.info(Pair.of("message", "upload res"), Pair.of("res", res), Pair.of("chapters", JSON.toJSONString(chapters)));
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            } else if ("xlsx".equalsIgnoreCase(fileExtension)) {
//
//                Map<String,Map<String, Object>> maps = ExcelReadUtils.readExcel(destination.toFile());
//
//                return new ResponseEntity<>(maps, HttpStatus.OK);
//            }

            // 将文件保存到服务器
            //File serverFile = new File(uploadDir, fileName);
            //file.transferTo(serverFile);
            return new ResponseEntity<>(resourceUrl, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>("Failed to upload file: " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return new ResponseEntity<>("Failed to upload file: " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
    }


    @PostMapping("/upload_excel_2_json")
    @Transactional
    public ResponseEntity<?> handleExcelFile2JSON(@RequestParam("file") MultipartFile file) {
        String fileName = file.getOriginalFilename();
        //String uploadDirectory = "uploads"; // 您可以更改为所需的上传目录
        try {
            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid file name");
            }
            // 获取文件后缀名
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
            // 保存文件到不同的目录
            Path destination = Paths.get(uploadDir, "others", originalFilename);

            // 创建目标文件夹，存在不做任何操作
            Files.createDirectories(destination.getParent());
            // 将上传的文件保存到目标路径
            Files.copy(file.getInputStream(), destination, StandardCopyOption.REPLACE_EXISTING);
            // 如果是压缩文件，则解压
            if ("xlsx".equalsIgnoreCase(fileExtension) || "xls".equalsIgnoreCase(fileExtension)) {

                Map<String,Map<String, Object>> maps = ExcelReadUtils.readExcel(destination.toFile());

                return new ResponseEntity<>(maps, HttpStatus.OK);
            }

            return new ResponseEntity<>("File uploaded successfully: " + fileName, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>("Failed to upload file: " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return new ResponseEntity<>("Failed to upload file: " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
    }




    @PostMapping(value = "/upload_files", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<?> handleLotsOFFileUpload(@RequestParam("file") MultipartFile[] files,
                                              @RequestParam(value = "book_id", defaultValue = "") Integer bookId) {
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            System.out.println("file: " +file + " bookId: " + bookId);
            //String uploadDirectory = "uploads"; // 您可以更改为所需的上传目录
            try {
                // 获取原始文件名
                String originalFilename = file.getOriginalFilename();
                if (originalFilename == null) {
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid file name");
                }
                // 获取文件后缀名
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
                // 保存文件到不同的目录
                Path destination;
                switch (fileExtension.toLowerCase()) {
                    case "jpg":
                    case "jpeg":
                    case "png":
                    case "gif":
                        destination = Paths.get(uploadDir, "images", getImgFileName(originalFilename));
                        break;
                    case "zip":
                        destination = Paths.get(uploadDir, "archives", originalFilename);
                        break;
                    default:
                        destination = Paths.get(uploadDir, "others", originalFilename);
                }

                // 创建目标文件夹，存在不做任何操作
                Files.createDirectories(destination.getParent());
                // 将上传的文件保存到目标路径
                Files.copy(file.getInputStream(), destination, StandardCopyOption.REPLACE_EXISTING);
                // 如果是压缩文件，则解压
                if ("zip".equalsIgnoreCase(fileExtension)) {
                    //unzip(destination, destination.getParent());
                    Path filePath = destination;
                    List<Chapter> chapters = decompressAndExtractBooks(filePath);
                    Logs.common.info(Pair.of("chapters", JSON.toJSONString(chapters)));
                    try {
                        boolean res = chapterService.saveBatch(chapters);
                        Logs.common.info(Pair.of("message", "upload res"), Pair.of("res", res), Pair.of("chapters", JSON.toJSONString(chapters)));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else if ("xlsx".equalsIgnoreCase(fileExtension) || "xls".equalsIgnoreCase(fileExtension)) {

                    Map<String,Map<String, Object>> maps = ExcelReadUtils.readExcel(destination.toFile());

                   // return new ResponseEntity<>(maps, HttpStatus.OK);
                }

                // 将文件保存到服务器
                //File serverFile = new File(uploadDir, fileName);
                //file.transferTo(serverFile);
                //return new ResponseEntity<>("File uploaded successfully: " + fileName, HttpStatus.OK);
            } catch (IOException e) {
                e.printStackTrace();
                //return new ResponseEntity<>("Failed to upload file: " + fileName, HttpStatus.INTERNAL_SERVER_ERROR);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        return new ResponseEntity<>("File uploaded successfully: ", HttpStatus.OK);
    }




    private String getImgFileName(String originalFilename) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String currentTimestamp = LocalDateTime.now().format(formatter);
        Random random = new Random();
        int randomNumber = random.nextInt(1000);
        char randomChar1 = (char) ('a' + random.nextInt(26));
        char randomChar2 = (char) ('a' + random.nextInt(26));
        String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
        String newName = currentTimestamp + randomNumber + randomChar1 + randomChar2 + extension;
        return newName;
    }



    private List<Chapter> decompressAndExtractBooks(Path compressedFile) throws IOException {
        List<Chapter> chaptes = new ArrayList<>();
        String destinationDirectory = uploadDir + "/chapters";
        String fileSeparator = System.getProperty("file.separator");
        try (ZipFile zipFile = new ZipFile(compressedFile.toFile())) {
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                if (entry.getName().startsWith("__MACOSX/")) {
                    continue;
                }
                if (!entry.isDirectory()) {
                    String entryName = entry.getName();
                    Path destinationPath = Paths.get(destinationDirectory, entryName);
                    Files.createDirectories(destinationPath.getParent());
                    Files.copy(zipFile.getInputStream(entry), destinationPath, StandardCopyOption.REPLACE_EXISTING);
                    Chapter chapter = new Chapter();
                    chapter.setBookId(16L);
                    chapter.setId(SnowFlake.getInstance().genUuid());
                    chapter.setChapterName(entryName.substring(entryName.lastIndexOf(fileSeparator) + 1));
                    chapter.setChapterPath("/static/" + destinationPath.toString().replace(uploadDir, ""));
                    chapter.setCreateTime(System.currentTimeMillis()/ 1000L);
                    chapter.setLastUpdateTime(System.currentTimeMillis()/ 1000L);
                    Logs.common.info(Pair.of("chapter", JSON.toJSONString(chapter)));
                    chaptes.add(chapter);
                }
            }
        }
        return chaptes;
    }



    public static void main(String[] args) {
        String postParams= "busi_ext%22%20%3A%20%22%7B%5C%22product_type%5C%22%3A8%2C%5C%22purchase_type%5C%22%3A3%2C%5C%22id%5C%22%3A%5C%22com.meitu.mtxx.consume.aiAvata.test.1000003%5C%22%2C%5C%22goods_type%5C%22%3A1%2C%5C%22origin%5C%22%3A%5C%22%5C%22%2C%5C%22entrance%5C%22%3A%5C%22test123%5C%22%2C%5C%22activity%5C%22%3A%5C%22ai-portrait%5C%22%2C%5C%22group_name%5C%22%3A%5C%22woman%5C%22%2C%5C%22ai_avatar_urls%5C%22%3A%5B%5C%22http%3A%5C%2F%5C%2Fstage.meitudata.com%5C%2Fxiuxiu-album-pic-test%5C%2Fai_avatar%5C%2F63b6741f2568cuoq7n3yln9054.jpeg%5C%22%2C%5C%22http%3A%5C%2F%5C%2Fstage.meitudata.com%5C%2Fxiuxiu-album-pic-test%5C%2Fai_avatar%5C%2F63b6741f25559661spokfr7665.jpeg%5C%22%2C%5C%22http%3A%5C%2F%5C%2Fstage.meitudata.com%5C%2Fxiuxiu-album-pic-test%5C%2Fai_avatar%5C%2F63b6741f23b6ahpmi6bh6r8585.jpeg%5C%22%2C%5C%22http%3A%5C%2F%5C%2Fstage.meitudata.com%5C%2Fxiuxiu-album-pic-test%5C%2Fai_avatar%5C%2F63b6741f257e8x8s7s1adv5640.jpeg%5C%22%5D%7D%22%2C%0A%20%20%22activity_id%22%20%3A%20%22ai-portrait%22%2C%0A%20%20%22entrance%22%20%3A%20%22test123%22%2C%0A%20%20%22function_id%22%20%3A%20%22999999%22%0A%7D%26free_trial_days%3D0%26gnum%3D1606056038%26iap_product%3D%7B%0A%20%20%22country_code%22%20%3A%20%22CN%22%2C%0A%20%20%22product_id%22%20%3A%20%22com.meitu.mtxx.consume.aiAvata.test.1000003%22%2C%0A%20%20%22symbol%22%20%3A%20%22%C2%A5%22%2C%0A%20%20%22promotion%22%20%3A%20%5B%0A%20%20%5D%2C%0A%20%20%22price%22%20%3A%2012%2C%0A%20%20%22currency_code%22%20%3A%20%22CNY%22%0A%7D";
        try {
            postParams = URLDecoder.decode(postParams, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        postParams = postParams.replaceAll("\\\\", "");
        try {
            JSONObject jo = JSON.parseObject(postParams);

        } catch (Exception e) {

        }
        System.out.println(postParams);
    }

}
